/*-------------------------------------------------------------------------

***************** Modification History ***********************************
   @doc
   @module packet.c - Functions to Control async packet building |
   @end

$Log: /SoftPay/SPK2SIM/Source/Protocol/packet.c $
**************************************************************************

   Copyright (C) 1999 by VeriFone, Inc.

   All rights reserved.  No part of this software may be reproduced,
   transmitted, transcribed, stored in a retrieval system, or translated
   into any language or computer language, in any form or by any means,
   electronic, mechanical, magnetic, optical, chemical, manual or otherwise,
   without the prior written permission of VeriFone, Inc.

---------------------------------------------------------------------------*/
#include <project.h>

#ifdef PET_DEFINED  

#define VSPACKET_C

#include <stdio.h>
#include <ascii.h>
#include <aclascii.h>
#include <acldev.h>
#include <string.h>
#include <aclconio.h>

#ifdef DEBUG_VSPACKET
#define DEBUG_95
#endif

#include <define.h>
#include <transact.h>
#include <packet.h>
#include <protocol.h>
#include <protomsg.h>
#include <init.h>
#include <msgfuncs.h>
#include <modem.h>
#include <mdmdefs.h>
#include <modemmsg.h>
#include <comm.h>
#include <spdebug.h>
#include <operate.h>

/*
 * get interchar timeout
 * as needed
 */
void vdGetInterCharTO(int* pinIcto) {
    MODEM_OBJECT* obModem = (MODEM_OBJECT*) 0;

    if (pinIcto) {
        obModem = (MODEM_OBJECT *) obCommunication.Data;
        (*pinIcto) = (int) obModem->shGetInterCharTO(obModem->srCPT);
    }

    return;
}

/*-------------------------------------------------------------------------
    Function :    inSendChar ()
    Description : Writes a single char to the modem, returns VS_SUCCESS if
                  write is success or in case of error while writing return
                  FAILURE.
    Parameters :
    Returns :     VS_ERR      : On errors
                  VS_SUCCESS  : On success
    Globals :
    Notes :
    Modification History :
      #     Date      Who                     Description
    ----- -------- ---------- ---------------------------------------------
      1   06/23/97  Kevin_v1   Replaced direct calls to Modem device with calls to COMM Object.
--------------------------------------------------------------------------*/

int inSendChar(char chSendChar) {
    if (obCommunication.fLinkUp != VS_TRUE)
        return(VS_ERR);

    if (obCommunication.inSend(&obCommunication, (char *) &chSendChar, 1, VS_FALSE, SEND_COMM_TIMEOUT, TRANSMITTING_MSG21) != 1)
        return(VS_ERR);

    SVC_WAIT(500);

    return(VS_SUCCESS);
}

/*-------------------------------------------------------------------------
    Function :
    Description : Time out in seconds, the function waits for inTimeOut
                  seconds for a specified char. Returns VS_SUCCESS of
                  VS_ERR, any other characters before timeout other than
                  the specified char on the way is absorbed by this function.
    Parameters :
    Returns :     VS_ERR      : On errors
                  VS_SUCCESS  : On success
    Globals :
    Notes :
    Modification History :
      #     Date      Who                     Description
    ----- -------- ---------- ---------------------------------------------
      1   08/15/97 Pat_G1     Fixed bugs so that it times out properly.
--------------------------------------------------------------------------*/

int inRecvChar(int inTimeOut,char chChar) {
    long lnInitialTickCount,
    lnCurrentTickCount;
    int inRetValue,
    inElapsedTime = 0;
    char chCharacterRead;



    SVC_TICKS(1, &lnInitialTickCount);

    do {
        inRetValue = inRecvAnyChar(inTimeout_SEC_To_TICKS(inTimeOut - inElapsedTime), &chCharacterRead);
        SVC_TICKS(1, &lnCurrentTickCount);
        inElapsedTime = (int) ((lnCurrentTickCount - lnInitialTickCount) / TICKS_PER_SEC);
    } while ((inRetValue == VS_SUCCESS) && (chCharacterRead != chChar) && (chCharacterRead != EOT) && ((inTimeOut - inElapsedTime) >= 0));

    if (chCharacterRead == EOT && chCharacterRead != chChar)  /* in case chChar is EOT    */
        inRetValue = VS_ABORT;

    if ((inTimeOut - inElapsedTime) < 0)
        inRetValue = VS_TIMEOUT;
    return(inRetValue);
}

/*-------------------------------------------------------------------------
    Function :
    Description : Time out in seconds, the function waits for inTimeOut
                  seconds for any char.
    Parameters :
    Returns :     VS_ERR      : On errors
                  VS_SUCCESS  : On success
    Globals :
    Notes :
    Modification History :
      #     Date      Who                     Description
    ----- -------- ---------- ---------------------------------------------
      1   06/23/97  Kevin_v1   Replaced direct calls to Modem device with calls to COMM Object
                               and replaced references to Modem Object Link Status as well.
      2   08/15/97  Pat_G1     Fixed bugs related to timeout problems.
      3   04/07/98  Kevin_V1   Reset any low-level errors which may have
                               been set by inReveive ()
--------------------------------------------------------------------------*/

int inRecvAnyChar(int inTimeOut,char* pchChar) {
    int inRetVal = VS_ERR;
    char chCharacterRead;
    unsigned long ulTicks;
    int inRecvTimeOut = 5;
    TRANSACTION_OBJECT* pobTran;

    if ((pobTran = pstGet_pobTran()) == NULL_CH)
        return VS_ERR;

    inRecvTimeOut *= 100; /* calc required for ACT library function (xmdm_receive_data)*/
    ulTicks = set_itimeout(NO_CLOCK_HANDLE(unsigned int) inTimeOut, TM_TICKS);
    do {
        chCharacterRead = NULL_CH;
        if ((inRetVal = obCommunication.inReceive(&obCommunication, &chCharacterRead, 1, inRecvTimeOut, RECEIVING_MSG21)) == 1) {
            inRetVal = VS_SUCCESS;
            *pchChar = chCharacterRead;
            /*
             *      Reset any low-level errors which may have been set by inReveive ()
             */
            vdSGErrorMessage(0L);
            memset(pobTran->szRespMsg, NULL_CH, RESP_MSG_SIZE + 1);
        }
    } while (inRetVal == VS_TIMEOUT && obCommunication.fLinkUp == VS_TRUE && CHECK_TIMEOUT(ulTicks));

    return(inRetVal);
} /* End of inRecvAnyChar() */

int inCheckLRC(char* stBuf,int inBufSize) {
    unsigned int uiLRCChar;

    uiLRCChar = SVC_CRC_CALC(0, stBuf, (inBufSize - 1));
    if (uiLRCChar != (unsigned int) stBuf[inBufSize - 1])
        return(VS_RXLRC);
    return(inBufSize);
}


/*-------------------------------------------------------------------------
    Function :      inReadVisaPacket ()
    Description :   Read visa packet looking for ETX and Check character ignoring post noise.
    Parameters :    
    Returns :
    Globals :
    Notes :
    
    Modification History :
      #     Date      Who                     Description
    ----- -------- ---------- ---------------------------------------------
      0   08/15/97 Kevin_V1   Initial Create
      1   03/20/98 Kevin_v1   Modified to prevent buffer over-run.
--------------------------------------------------------------------------*/

int inReadVisaPacket(PACKET_OBJECT* psrCommPackage) {
    int inRetVal = VS_SUCCESS;
    int inResult;
    int inDex;
    int ICTO;

    vdGetInterCharTO(&ICTO);
    ICTO *= 100; /* calc required for ACT library function (xmdm_receive_data)*/ 

    inDex = 1;
    do {
        inResult = obCommunication.inReceive(&obCommunication, (char *) &psrCommPackage->pchReceiveBuff[inDex], psrCommPackage->inReceiveBuffSize - inDex, ICTO, RECEIVING_MSG21);
        if (inResult < 0) {
            inRetVal = inResult;
            break;
        }
        inDex += inResult;
        /*
         *      Prevent Buffer Over-Run!
         */
        if (inDex >= psrCommPackage->inReceiveBuffSize) {
            inRetVal = VS_RXLRC;
            break;
        }
        /*
         *      Check for complete Packet...
         */
        if (psrCommPackage->pchReceiveBuff[inDex - 2] == ETX)
            break;
    } while (VS_TRUE);

    /*
     *      If we go data and timed out, check for noise after packet...
     */
    if (inRetVal == VS_TIMEOUT && inDex >= 3) {
        do {
            inDex--;
        } while (inDex >= 3 && psrCommPackage->pchReceiveBuff[inDex - 2] != ETX);
        if (inDex >= 3)
            inRetVal = VS_SUCCESS;
    }

    if (inRetVal == VS_SUCCESS) {
        psrCommPackage->inReceiveSize = inDex;
        inRetVal = inCheckLRC((char *) &(psrCommPackage->pchReceiveBuff[1]), inDex);
    }

    return (inRetVal);
} /* End of inReadVisaPacket() */

#undef VSPACKET_C

#endif //PET_DEFINED    

